import Vue from 'vue';
import 'intersection-observer'

const options = {
  root: document.getElementById('#app'), //根元素
  threshold: 1.0 //元素完全出现/离开浏览器视图时执行callback函数
}

let timeOut = {}
const wateTime = 3000
const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    let reportData = null
    try {
      reportData = JSON.parse(entry.target.getAttribute('report-data'));
    } catch (err) {
      reportData = null;
      console.error('数据格式异常', err);
    }
    //元素完全显示在视图中
    if (entry.isIntersecting) {
      console.log(`${reportData.key} 完全进入视图`)
      //元素实际高度
      reportData.clientHeight = entry.target.clientHeight
      //元素曝光3秒后上报数据
      timeOut[reportData.uniqTag] = setTimeout(() => {
        console.log(`${reportData.key} 停留时间超过3秒，上报数据${JSON.stringify(reportData)}`)
        timeOut[reportData.uniqTag] = null
      }, wateTime)
    } else {
      if (timeOut[reportData.uniqTag]) {
        console.log(`${reportData.key} 停留时间不超过3秒，清除定时器`)
        clearTimeout(timeOut[reportData.uniqTag])
        timeOut[reportData.uniqTag] = null
      }
    }
  });
}, options);

const addListenner = (ele) => {
  //唯一标识在这里赋值是因为 IntersectionObserver 会在每次元素出现或离开浏览器视图时执行回调
  let attrValue = JSON.parse(ele.attributes['report-data']?.value)
    //为每一个元素赋值唯一标识
  if (attrValue) {
    attrValue.uniqTag = uuid()
    ele.setAttribute('report-data', JSON.stringify(attrValue))
  }
  observer.observe(ele);
};

/**
 * 补全字符
 * @param {*} num 初始值
 * @param {*} len 需要补全的位数
 * @param {*} placeholder 补全的值
 * @returns 补全后的值
 */
const pad = (num, len, placeholder = '0') => {
  const str = String(num);
  if (str.length < len) {
    let result = str;
    for (let i = 0; i < len - str.length; i += 1) {
      result = placeholder + result;
    }
    return result;
  }
  return str;
}

/**
 * 获取一个随机字符串(全局唯一标识符)
 */
function uuid() {
  const date = new Date();
  // yyyy-MM-dd的16进制表示,7位数字
  const hexDate = parseInt(`${date.getFullYear()}${pad(date.getMonth() + 1, 2)}${pad(date.getDate(), 2)}`, 10).toString(16);
  // hh-mm-ss-ms的16进制表示，最大也是7位
  const hexTime = parseInt(`${pad(date.getHours(), 2)}${pad(date.getMinutes(), 2)}${pad(date.getSeconds(), 2)}${pad(date.getMilliseconds(), 3)}`, 10).toString(16);
  // 第8位数字表示后面的time字符串的长度
  let guid = hexDate + hexTime.length + hexTime;
  // 补充随机数，补足32位的16进制数
  while (guid.length < 32) {
    guid += Math.floor(Math.random() * 16).toString(16);
  }
  // 分为三段，前两段包含时间戳信息
  return `${guid.slice(0, 8)}-${guid.slice(8, 16)}-${guid.slice(16)}`;
}

Vue.directive('stay', {
  bind: addListenner,
});